import { ISerializer } from '../types';

/**
 * JSON序列化器
 */
export class JsonSerializer implements ISerializer {
    /** 缩进空格数 */
    private readonly indent: number;

    /**
     * 构造函数
     * @param indent 缩进空格数
     */
    constructor(indent: number = 2) {
        this.indent = indent;
    }

    /**
     * 序列化数据
     * @param data 数据数组
     */
    serialize(data: any[]): string {
        return JSON.stringify(data, null, this.indent);
    }

    /**
     * 反序列化数据
     * @param content 序列化的内容
     */
    deserialize(content: string): any[] {
        return JSON.parse(content);
    }

    /**
     * 获取默认文件扩展名
     */
    getDefaultExtension(): string {
        return '.json';
    }
}

/**
 * CSV序列化器
 */
export class CsvSerializer implements ISerializer {
    /** 分隔符 */
    private readonly delimiter: string;
    
    /** 是否包含表头 */
    private readonly hasHeader: boolean;
    
    /** 换行符 */
    private readonly lineBreak: string = '\n';
    
    /** 引号字符 */
    private readonly quote: string = '"';
    
    /** 转义引号 */
    private readonly escapedQuote: string = '""';

    /**
     * 构造函数
     * @param delimiter 分隔符
     * @param hasHeader 是否包含表头
     */
    constructor(delimiter: string = ',', hasHeader: boolean = true) {
        this.delimiter = delimiter;
        this.hasHeader = hasHeader;
    }

    /**
     * 序列化数据
     * @param data 数据数组
     */
    serialize(data: any[]): string {
        if (data.length === 0) return '';

        const headers = Object.keys(data[0]);
        const rows = data.map(item => 
            headers.map(header => this.escapeCsvValue(item[header])).join(this.delimiter)
        );

        if (this.hasHeader) {
            rows.unshift(headers.join(this.delimiter));
        }

        return rows.join(this.lineBreak);
    }

    /**
     * 反序列化数据
     * @param content 序列化的内容
     */
    deserialize(content: string): any[] {
        if (!content) return [];

        const rows = content.split(this.lineBreak).filter(row => row.trim());
        if (rows.length === 0) return [];

        let headerRow = 0;
        let headers: string[];

        if (this.hasHeader) {
            headers = this.parseCsvRow(rows[0]);
            headerRow = 1;
        } else {
            headers = this.generateHeaders(this.parseCsvRow(rows[0]).length);
        }

        return rows.slice(headerRow).map(row => {
            const values = this.parseCsvRow(row);
            const item: any = {};
            headers.forEach((header, index) => {
                item[header] = this.parseValue(values[index]);
            });
            return item;
        });
    }

    /**
     * 获取默认文件扩展名
     */
    getDefaultExtension(): string {
        return '.csv';
    }

    /**
     * 转义CSV值
     * @param value 值
     */
    private escapeCsvValue(value: any): string {
        if (value === null || value === undefined) {
            return '';
        }
        const str = String(value);
        if (str.includes(this.delimiter) || str.includes(this.quote) || str.includes(this.lineBreak)) {
            return `${this.quote}${str.replace(new RegExp(this.quote, 'g'), this.escapedQuote)}${this.quote}`;
        }
        return str;
    }

    /**
     * 解析CSV行
     * @param row 行内容
     */
    private parseCsvRow(row: string): string[] {
        const values: string[] = [];
        let currentValue = '';
        let inQuotes = false;

        for (let i = 0; i < row.length; i++) {
            const char = row[i];
            if (char === this.quote) {
                if (inQuotes && row[i + 1] === this.quote) {
                    currentValue += this.quote;
                    i++;
                } else {
                    inQuotes = !inQuotes;
                }
            } else if (char === this.delimiter && !inQuotes) {
                values.push(currentValue);
                currentValue = '';
            } else {
                currentValue += char;
            }
        }
        values.push(currentValue);
        return values;
    }

    /**
     * 生成默认表头
     * @param count 列数
     */
    private generateHeaders(count: number): string[] {
        return Array.from({ length: count }, (_, i) => `column${i + 1}`);
    }

    /**
     * 解析值
     * @param value 字符串值
     */
    private parseValue(value: string): any {
        if (value === '') return null;
        if (value === 'true') return true;
        if (value === 'false') return false;
        if (!isNaN(Number(value))) return Number(value);
        return value;
    }
}

/**
 * 创建序列化器
 * @param type 序列化类型
 * @param options 选项
 */
export function createSerializer(type: string, options?: any): ISerializer {
    switch (type) {
        case 'json':
            return new JsonSerializer(options?.indent ?? 2);
        case 'csv':
            return new CsvSerializer(
                options?.delimiter,
                options?.hasHeader ?? true
            );
        default:
            throw new Error(`Unsupported serializer type: ${type}`);
    }
}
